package org.springframework.samples.countries.web.translate;

import java.util.List;
import java.util.Stack;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import pikes.ecma.FunctionCall;
import pikes.ecma.IAssignmentExpression;
import pikes.ecma.IExpression;
import pikes.ecma.IMemberExpression;
import pikes.ecma.MemberPropertyAccess;

public class InvokeVirtual implements ByteCodeOperation {

	protected static final Log translatorLogger = LogFactory.getLog("Translator");

	private String name = null;

	public InvokeVirtual(String name) {
		super();
		this.name = name;
	}

	public void execute(int numberOfParameters, Stack<Object> stack, List<String> localVariables) {
		translatorLogger.info("INVOKEVIRTUAL: method '" + name + "'");
		Stack<IExpression> parameters = new Stack<IExpression>();

		int stackSize = stack.size();

		if (stackSize < 1) {
			throw new IllegalStateException();
		}

		if (stackSize > 1) {
			int i = stackSize;
			while (i > 1) {
				parameters.push((IExpression) stack.pop());
				i--;
			}
		}

		IMemberExpression memberExpression = (IMemberExpression) stack.pop();
		FunctionCall call = new FunctionCall(new MemberPropertyAccess(memberExpression, name));

		while (!parameters.isEmpty()) {
			IAssignmentExpression parameter = (IAssignmentExpression) parameters.pop();
			call.addArgument(parameter);
		}

		stack.push(call);
	}

	@Override
	public String toString() {
		return "invokevirtual " + name;
	}

}